package com.flyqiu.common.tools;

import org.apache.commons.lang3.StringUtils;

import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * FlyQiuStreamTools 提供了流处理中对对象进行去重的工具方法。
 */
public class FlyQiuStreamTools {
    /**
     * 根据指定字段对对象流进行去重。
     *
     * @param keyExtractor 一个函数，用于从对象中提取去重的字段值。
     * @param <T> 对象的类型。
     * @return 返回一个Predicate，用于对象流的去重过滤。
     */
    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        ConcurrentHashMap<Object, Boolean> map = new ConcurrentHashMap<>();
        // 使用ConcurrentHashMap来存储已处理的字段值，实现去重逻辑。
        return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    /**
     * 根据指定字符串字段对对象流进行去重，同时忽略空字符串和null值。
     *
     * @param keyExtractor 一个函数，用于从对象中提取作为去重依据的字符串字段。
     * @param <T> 对象的类型。
     * @return 返回一个Predicate，用于对象流的去重过滤。
     */
    public static <T> Predicate<T> distinctAndNotBlankByKey(Function<? super T, String> keyExtractor) {
        ConcurrentHashMap<String, Boolean> map = new ConcurrentHashMap<>();

        // 对提取的字段值进行空检查，忽略空字符串和null，再进行去重处理。
        return t -> {
            String apply = keyExtractor.apply(t);
            if (StringUtils.isBlank(apply)) {
                return false;
            }
            return map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
        };
    }
}
